<template>
  <div>
    <uploader
      :autoStart="false"
      :options="options"
      :file-status-text="statusText"
      class="uploader-example"
      @complete="complete"
      @file-success="fileSuccess"
      @files-added="filesAdded"
    >
      <uploader-unsupport></uploader-unsupport>
      <uploader-drop>
        <!-- <p>将视频拖放到此处以上传</p> -->
        <!-- <uploader-btn>选择文件</uploader-btn> -->
        <!-- <uploader-btn :attrs="attrsImage">选择图片</uploader-btn> -->
        <uploader-btn :attrs="attrsVideo">选择视频</uploader-btn>
        <!-- <uploader-btn :directory="true">选择文件夹</uploader-btn> -->
      </uploader-drop>
      <div
        :element-loading-text="title"
        element-loading-spinner="el-icon-loading"
        element-loading-background="rgba(0, 0, 0, 0.8)"
        v-loading="loading"
        element-loading-custom-class="my-loading"
      >
        <uploader-list>
          <!--通过slot-scope绑定文件实例-->
          <div slot-scope="props">
            <div v-for="file in props.fileList" :key="file.name">
              <uploader-file
                :list="true"
                :file="file"
                :underline="false"
                target="_blank"
              ></uploader-file>
              <!-- <el-button
              @click="
                handleVideoPreview(
                  downloadFileUrl + getFileDownLoadPath + file.relativePath
                )
              "
            >
            </el-button> -->
            </div>
          </div>
        </uploader-list>
      </div>
      <!-- <uploader-files> </uploader-files> -->
    </uploader>
    <!-- <br />
    <el-button @click="allStart()" :disabled="disabled">全部开始</el-button>
    <el-button @click="allStop()" style="margin-left: 4px">全部暂停</el-button>
    <el-button @click="allRemove()" style="margin-left: 4px"
      >全部移除</el-button
    > -->
    <el-dialog
      v-if="dialogVisible"
      title="视频预览"
      width="800px"
      append-to-body
    >
      <vue-core-video-player :src="videoSource" controls="auto" autoplay />
    </el-dialog>
  </div>
</template>

<script>
import axios from "axios";
import SparkMD5 from "spark-md5";
// import storage from "store";
// import { ACCESS_TOKEN } from '@/store/mutation-types'
import { getToken } from "@/utils/auth";
export default {
  props: {
    videosList: {
      type: String,
      default: "",
    },
    fileDownLoadPath: {
      type: String,
      default: "/common/download?fileName=",
    },
    fileUpLoadPath: {
      type: String,
      default: "/common/upload",
    },
  },
  data() {
    return {
      //判断全部完成依据
      videoOver: false,
      //上传的视频
      videoData: [],
      //选择视频按钮
      // uploaderBtn: true,
      //loading文字
      title: "",
      uploaderDrop: true,
      //loading弹框
      loading: false,
      //视频预览地址
      videoSource: "",
      //视频预览窗口是否显示
      dialogVisible: false,
      downloadFileUrl: process.env.VUE_APP_FILE_SYSTEM,
      skip: false,
      options: {
        target: process.env.VUE_APP_BASE_API + "/upload/chunk",
        // 开启服务端分片校验功能
        testChunks: true,
        parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) {
          return parsedTimeRemaining
            .replace(/\syears?/, "年")
            .replace(/\days?/, "天")
            .replace(/\shours?/, "小时")
            .replace(/\sminutes?/, "分钟")
            .replace(/\sseconds?/, "秒");
        },
        // 服务器分片校验函数
        checkChunkUploadedByResponse: (chunk, message) => {
          const result = JSON.parse(message);
          if (result.data.skipUpload) {
            this.skip = true;
            return true;
          }
          return (result.data.uploaded || []).indexOf(chunk.offset + 1) >= 0;
        },
        headers: {
          // 在header中添加的验证，请根据实际业务来
          // "Access-Token": storage.get(ACCESS_TOKEN),
          Authorization: "Bearer " + getToken(),
        },
      },
      attrsImage: {
        accept: "image/*",
      },
      attrsVideo: {
        accept: "video/*",
      },
      statusText: {
        success: "上传成功",
        error: "上传出错了",
        uploading: "上传中...",
        paused: "暂停中...",
        waiting: "等待中...",
        cmd5: "计算文件MD5中...",
      },
      fileList: [],
      disabled: true,
      //视频地址
      videoList: [],
    };
  },
  created() {
    this.allRemove();
  },
  watch: {
    fileList(o, n) {
      this.disabled = false;
    },
  },
  computed: {
    getFileDownLoadPath() {
      return this.fileDownLoadPath;
    },
  },
  methods: {
    //预览
    handleVideoPreview(file) {
      this.videoSource = file;
      this.dialogVisible = true;
    },
    //分片上传完成
    fileSuccess(rootFile, file, response, chunk) {
      //等待后端返回地址
      this.loading = true;
      this.title = "视频合并中";
      const result = JSON.parse(response);
      if (result.code == 200 && !this.skip) {
        axios
          .post(
            process.env.VUE_APP_BASE_API + "/upload/merge",
            {
              identifier: file.uniqueIdentifier,
              filename: file.name,
              totalChunks: chunk.offset,
            },
            {
              headers: { Authorization: "Bearer " + getToken() },
            }
          )
          .then((res) => {
            if (res.data.success) {
              // console.log("fileList:", this.fileList);
              for (let i = 0; i < this.fileList.length; i++) {
                if (this.fileList[i].name == res.data.oldName) {
                  this.fileList[i].relativePath = res.data.fileName;
                }
              }
              // console.log("fileList:", this.fileList);
              this.loading = false;
              if (this.videoOver === true) {
                this.messageBox();
                // console.log(123);
              }
              // this.uploaderBtn = false;
            } else {
            }
          })
          .catch(function (error) {});
      } else {
      }
      if (this.skip) {
        this.skip = false;
      }
    },
    //上传完成的回调
    complete() {
      this.videoOver = true;
      // this.messageBox();
    },
    filesAdded(file, fileList, event) {
      // console.log(file);
      file.forEach((e) => {
        this.fileList.push(e);
        this.computeMD5(e);
      });
    },
    //开始上传，分片
    computeMD5(file) {
      this.uploaderDrop = false;
      this.loading = true;
      this.title = "视频分片中";
      let fileReader = new FileReader();
      let time = new Date().getTime();
      let blobSlice =
        File.prototype.slice ||
        File.prototype.mozSlice ||
        File.prototype.webkitSlice;
      let currentChunk = 0;
      const chunkSize = 20 * 1024 * 1024;
      let chunks = Math.ceil(file.size / chunkSize);
      let spark = new SparkMD5.ArrayBuffer();
      // 文件状态设为"计算MD5"
      file.cmd5 = true; //文件状态为“计算md5...”
      file.pause();
      loadNext();
      fileReader.onload = (e) => {
        spark.append(e.target.result);
        if (currentChunk < chunks) {
          currentChunk++;
          loadNext();
          // 实时展示MD5的计算进度
          // console.log(
          //   `第${currentChunk}分片解析完成, 开始第${
          //     currentChunk + 1
          //   } / ${chunks}分片解析`
          // );
        } else {
          let md5 = spark.end();
          // console.log(
          //   `MD5计算完毕：${file.name} \nMD5：${md5} \n分片：${chunks} 大小:${
          //     file.size
          //   } 用时：${new Date().getTime() - time} ms`
          // );
          spark.destroy(); //释放缓存
          file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
          file.cmd5 = false; //取消计算md5状态
          // console.log(999,file.uniqueIdentifier);
          //开始分片时候拿到视频name
          this.videoData = file.uniqueIdentifier;
          this.$emit("videoData", this.videoData);
          file.resume(); //开始上传
          this.loading = false;
        }
      };
      fileReader.onerror = function () {
        this.error(`文件${file.name}读取出错，请检查该文件`);
        file.cancel();
      };
      function loadNext() {
        let start = currentChunk * chunkSize;
        let end =
          start + chunkSize >= file.size ? file.size : start + chunkSize;
        fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
      }
    },
    //全部开始
    allStart() {
      this.fileList.map((e) => {
        if (e.paused) {
          e.resume();
        }
      });
    },
    //暂停
    allStop() {
      this.fileList.map((e) => {
        if (!e.paused) {
          e.pause();
        }
      });
    },
    //全部移除
    allRemove() {
      this.fileList.map((e) => {
        e.cancel();
      });
      this.fileList = [];
    },
    //是否确定上传
    messageBox() {
      this.$alert("上传完成，点击确定完成上传", "是否确定上传", {
        confirmButtonText: "确定",
        //确定后执行的回调
        callback: () => {
          this.$message({
            type: "success",
            message: "该视频上传已完成！",
          });
          for (const arr of this.fileList) {
            if (arr.relativePath != arr.name) {
              this.videoList.push(arr.relativePath);
            }
          }
          // this.uploaderBtn = true;
          this.videoList = this.videoList.toString();
          this.$emit("videosListData", this.videoList);
        },
      });
    },
    //手动传递数据
    relativePathList() {
      for (const arr of this.fileList) {
        if (arr.name != "") {
          if (arr.relativePath != arr.name) {
            this.videoList.push(arr.relativePath);
          }
        }
      }
      if (this.videoList.length > 0) {
        this.videoList = this.videoList.toString();
        this.$emit("videosListData", this.videoList);
      }
    },
  },
};
</script>

<style lang="scss">
.uploader-example {
  width: 100%;
  padding: 15px;
  margin: 0px auto 0;
  font-size: 12px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
}
.uploader-example .uploader-btn {
  margin-right: 4px;
}
.uploader-example .uploader-list {
  max-height: 440px;
  overflow: auto;
  overflow-x: hidden;
  overflow-y: auto;
}
.my-loading {
  .el-loading-spinner {
    .el-loading-text {
      margin-left: 5px;
      display: inline-block !important;
    }
  }
}
</style>
